home *** CD-ROM | disk | FTP | other *** search
/ Aminet 1 / Aminet - June 1993 [Walnut Creek].iso / usenet / sources / volume89 / dos / fs / frag.1 < prev    next >
Encoding:
Internet Message Format  |  1989-11-13  |  41.3 KB

  1. Path: wuarchive!texbell!texsun!newstop!sun!swap!page
  2. From: page%swap@Sun.COM (Bob Page)
  3. Newsgroups: comp.sources.amiga
  4. Subject: v89i201:  frag - show disk & file fragementation
  5. Message-ID: <127772@sun.Eng.Sun.COM>
  6. Date: 13 Nov 89 01:46:43 GMT
  7. Sender: news@sun.Eng.Sun.COM
  8. Lines: 1162
  9. Approved: page@sun.com
  10.  
  11. Submitted-by: dg3i+@andrew.cmu.edu (David Gay)
  12. Posting-number: Volume 89, Issue 201
  13. Archive-name: dos/fs/frag.1
  14.  
  15. Here are two utilities, "blocks" and "free",  to show disk and file
  16. fragmentation.
  17.  
  18. [uuencoded executables included.  ..bob]
  19.  
  20. # This is a shell archive.
  21. # Remove anything above and including the cut line.
  22. # Then run the rest of the file through 'sh'.
  23. # Unpacked files will be owned by you and have default permissions.
  24. #----cut here-----cut here-----cut here-----cut here----#
  25. #!/bin/sh
  26. # shar: SHell ARchive
  27. # Run the following text through 'sh' to create:
  28. #    lmkfile
  29. #    free.c
  30. #    free.doc
  31. #    free.hdr
  32. #    free.uu
  33. #    blocks.c
  34. #    blocks.doc
  35. #    blocks.uu
  36. # This is archive 1 of a 1-part kit.
  37. # This archive created: Sun Nov 12 17:42:24 1989
  38. echo "extracting lmkfile"
  39. sed 's/^X//' << \SHAR_EOF > lmkfile
  40. Xall: blocks free
  41. X
  42. Xblocks: blocks.c
  43. X    lc -v -O blocks
  44. X    @blink from lib:cback.o blocks.o to blocks lib lib:lc.lib batch nodebug def
  45. Xine __main=__tinymain verbose sc sd
  46. X
  47. Xfree: free.c
  48. X    lc -cf -v -rr -O free
  49. X    @blink from lib:cback.o free.o to free lib lib:lcr.lib batch nodebug define
  50. X @_main=@_tinymain verbose sc sd
  51. X
  52. SHAR_EOF
  53. echo "extracting free.c"
  54. sed 's/^X//' << \SHAR_EOF > free.c
  55. X#include <exec/types.h>
  56. X#include <exec/io.h>
  57. X#include <libraries/dos.h>
  58. X#include <libraries/dosextens.h>
  59. X#include <libraries/filehandler.h>
  60. X#include <intuition/intuition.h>
  61. X#include <workbench/startup.h>
  62. X#include <devices/trackdisk.h>
  63. X
  64. X#include <proto/exec.h>
  65. X#include <proto/dos.h>
  66. X#include <proto/graphics.h>
  67. X#include <proto/intuition.h>
  68. X
  69. X#include <stdio.h>
  70. X#include <stdlib.h>
  71. X#include <string.h>
  72. X
  73. X#define error(s) { if (cli) Write(_Backstdout, (s), strlen(s)); }
  74. X
  75. X/* border sizes, shouldn't be hard coded ... */
  76. X#define XLEFT 2
  77. X#define XRIGHT 2
  78. X#define YTOP 10
  79. X#define YBOTTOM 1
  80. X/* Max/Min window size */
  81. X#define MAXHEIGHT (200 - YTOP - YBOTTOM)
  82. X#define MAXWIDTH   (640 - XLEFT - XRIGHT)
  83. X#define MINWIDTH 200
  84. X#define MINHEIGHT 80
  85. X
  86. X/* Detach info */
  87. Xlong _stack = 2000;
  88. Xchar *_procname = "freeblks";
  89. Xlong _priority = 0;
  90. Xlong _BackGroundIO = TRUE;
  91. Xextern long _Backstdout;
  92. X
  93. Xtypedef struct FileInfoBlock FIB;
  94. Xtypedef struct InfoData INFO;
  95. X
  96. Xextern struct IntuitionBase *IntuitionBase;
  97. Xextern struct GfxBase *GfxBase;
  98. X
  99. X/* Device access */
  100. Xstruct MsgPort *port;
  101. Xstruct IOStdReq *io;
  102. Xint DevOpen;
  103. X/* Partition characteristics */
  104. Xlong blk_size, blk_offset, root_blk, *secbuf, *secbuf2;
  105. Xstruct Window *win;
  106. X/* size of window, of each block, etc */
  107. Xint xdiv, rectw, recth, width, height;
  108. Xint cli;
  109. X
  110. Xstruct NewWindow newwin = {
  111. X    0, 0,
  112. X    0, 0,
  113. X    -1, -1,
  114. X    CLOSEWINDOW,
  115. X    WINDOWDRAG | WINDOWDEPTH | WINDOWCLOSE | SMART_REFRESH | NOCAREREFRESH | RM
  116. XBTRAP,
  117. X    NULL,
  118. X    NULL,
  119. X    NULL,
  120. X    NULL,
  121. X    NULL,
  122. X    0, 0, 0, 0,
  123. X    WBENCHSCREEN
  124. X};
  125. X
  126. X/* bcpl string -> C string */
  127. Xchar *btoc_str(char *to, BSTR from)
  128. X{
  129. X    char *cstr = (char *)BADDR(from);
  130. X
  131. X    strncpy(to, cstr + 1, *cstr);
  132. X    to[*cstr] = '\0';
  133. X
  134. X    return to;
  135. X}
  136. X
  137. X/* Calculate coords on window for block 'block' on disk */
  138. Xvoid cvt_point(long *x, long *y, long block)
  139. X{
  140. X    *x = rectw * (block / (xdiv * height)) + XLEFT;
  141. X    *y = recth * (block % height) + YTOP;
  142. X}
  143. X
  144. X/* Calc size, & open window */
  145. Xint prepare_window(struct DeviceNode *dev)
  146. X{
  147. X    struct FileSysStartupMsg *msg = (struct FileSysStartupMsg *)BADDR(dev->dn_S
  148. Xtartup);
  149. X    ULONG *env = (ULONG *)BADDR(msg->fssm_Environ);
  150. X    long blkscyl = env[DE_NUMHEADS] * env[DE_BLKSPERTRACK];
  151. X    long numcyls = env[DE_UPPERCYL] - env[DE_LOWCYL] + 1;
  152. X    long blks;
  153. X    static char title[80];
  154. X
  155. X    if (blkscyl <= MAXHEIGHT) /* Do a "nice" presentation, 1 cylinder per vert
  156. Xline */
  157. X    {
  158. X        height = blkscyl;
  159. X        xdiv = (numcyls / MAXWIDTH + 1); /* Nb of cylinders per vertical line *
  160. X/
  161. X        width = numcyls / xdiv;
  162. X    }
  163. X    else /* Just squash em in */
  164. X    {
  165. X        blks = numcyls * blkscyl;
  166. X        height = MAXHEIGHT;
  167. X        xdiv = (blks / MAXHEIGHT + 1) / MAXWIDTH + 1;
  168. X        width = (blks / MAXHEIGHT + 1) / xdiv;
  169. X    }
  170. X    /* Size of rect for 1 block */
  171. X    rectw = MINWIDTH / width + 1;
  172. X    recth = MINHEIGHT / height + 1;
  173. X
  174. X    /* Open window */
  175. X    btoc_str(title, dev->dn_Name);
  176. X    strcat(title, ":, free blocks");
  177. X    newwin.Title = title;
  178. X    newwin.Width = rectw * width + XLEFT + XRIGHT;
  179. X    newwin.Height = recth * height + YTOP + YBOTTOM;
  180. X
  181. X    if (win = OpenWindow(&newwin))
  182. X    {
  183. X        SetAPen(win->RPort, 2);
  184. X        RectFill(win->RPort, XLEFT, YTOP, win->Width - XRIGHT - 1, win->Height
  185. X- YBOTTOM - 1);
  186. X        SetAPen(win->RPort, 3);
  187. X        return TRUE;
  188. X    }
  189. X    return FALSE;
  190. X}
  191. X
  192. X/* Reads sector at offset 'sector' from disk ('sector' must be a multiple of 51
  193. X2) */
  194. XBYTE *ReadSector(long sector, BYTE *buf, long len)
  195. X{
  196. X    io->io_Command = CMD_READ;
  197. X    io->io_Length = len;
  198. X    io->io_Data = (APTR)buf;
  199. X    io->io_Offset = sector;
  200. X    DoIO((struct IORequest *)io);
  201. X    return (io->io_Error == 0) ? buf : NULL;
  202. X}
  203. X
  204. X/* Turn motor on/off */
  205. Xvoid Motor(int on)
  206. X{
  207. X    io->io_Command = TD_MOTOR;
  208. X    io->io_Length = on;
  209. X    DoIO((struct IORequest *)io);
  210. X}
  211. X
  212. X/* Find device by name */
  213. Xstruct DeviceNode *FindDevice(char *name)
  214. X{
  215. X    struct DeviceNode *devlist;
  216. X    int l = strlen(name), l2;
  217. X    char *name2;
  218. X
  219. X    Forbid();
  220. X    devlist = (struct DeviceNode *)BADDR(((struct DosInfo *)BADDR(((struct Root
  221. XNode *)(DOSBase->dl_Root))->rn_Info))->di_DevInfo);
  222. X    for (;devlist; devlist = (struct DeviceNode *)BADDR(devlist->dn_Next))
  223. X        if (devlist->dn_Type == DLT_DEVICE)
  224. X        {
  225. X            name2 = (char *)BADDR(devlist->dn_Name);
  226. X            l2 = *name2;
  227. X            if (l == l2 && strnicmp(name, name2 + 1, l) == 0) break;
  228. X        }
  229. X
  230. X    Permit();
  231. X    return devlist;
  232. X}
  233. X
  234. X/* Find device by task */
  235. Xstruct DeviceNode *TaskDevice(struct MsgPort *task)
  236. X{
  237. X    struct DeviceNode *devlist;
  238. X
  239. X    Forbid();
  240. X    devlist = (struct DeviceNode *)BADDR(((struct DosInfo *)BADDR(((struct Root
  241. XNode *)(DOSBase->dl_Root))->rn_Info))->di_DevInfo);
  242. X    for (;devlist; devlist = (struct DeviceNode *)BADDR(devlist->dn_Next))
  243. X        if (devlist->dn_Type == DLT_DEVICE)
  244. X        {
  245. X            if (task == devlist->dn_Task) { Permit(); return devlist; }
  246. X        }
  247. X
  248. X    Permit();
  249. X    return NULL;
  250. X}
  251. X
  252. X/* Reads block n of *partition* */
  253. XBYTE *ReadBlock(long *buf, long n)
  254. X{
  255. X    return(ReadSector((blk_offset + n) * blk_size * 4, (BYTE *)buf, blk_size *
  256. X4));
  257. X}
  258. X
  259. X/* Get partition characteristics, open device */
  260. Xint setup(struct DeviceNode *dev)
  261. X{
  262. X    char devname[32];
  263. X    struct FileSysStartupMsg *msg = (struct FileSysStartupMsg *)BADDR(dev->dn_S
  264. Xtartup);
  265. X    ULONG *env = (ULONG *)BADDR(msg->fssm_Environ);
  266. X    long err;
  267. X
  268. X    port = CreatePort(0, 0);
  269. X    if (!port)
  270. X    {
  271. X        error("No port!\n");
  272. X        return FALSE;
  273. X    }
  274. X    io = CreateStdIO(port);
  275. X    if (!io)
  276. X    {
  277. X        error("No IO request!\n");
  278. X        return FALSE;
  279. X    }
  280. X    err = OpenDevice(btoc_str(devname, msg->fssm_Device), msg->fssm_Unit, (stru
  281. Xct IORequest *)io, msg->fssm_Flags);
  282. X    if (err)
  283. X    {
  284. X        error("Device not opened\n");
  285. X        return FALSE;
  286. X    }
  287. X    DevOpen = TRUE;
  288. X    blk_size = env[DE_SIZEBLOCK];
  289. X    blk_offset = env[DE_LOWCYL] * env[DE_BLKSPERTRACK] * env[DE_NUMHEADS];
  290. X    root_blk = (env[DE_BLKSPERTRACK] * env[DE_NUMHEADS] * (env[DE_UPPERCYL] - e
  291. Xnv[DE_LOWCYL] + 1) - 1 + env[DE_RESERVEDBLKS]) / 2;
  292. X    secbuf = (long *)AllocMem(2 * 4 * blk_size, env[DE_MEMBUFTYPE]);
  293. X    if (!secbuf)
  294. X    {
  295. X        error("No sector buffer!\n");
  296. X        return FALSE;
  297. X    }
  298. X    secbuf2 = secbuf + blk_size;
  299. X    return TRUE;
  300. X}
  301. X
  302. X/* Close device */
  303. Xvoid release(void)
  304. X{
  305. X    if (secbuf) FreeMem((char *)secbuf, 2 * 4 * blk_size);
  306. X    if (DevOpen) CloseDevice((struct IORequest *)io);
  307. X    if (io) DeleteStdIO(io);
  308. X    if (port) DeletePort(port);
  309. X}
  310. X
  311. X/* Displays free blocks on device dev. For OFS/FFS !!! */
  312. Xvoid disp_free(struct DeviceNode *dev)
  313. X{
  314. X    struct FileSysStartupMsg *fmsg = (struct FileSysStartupMsg *)BADDR(dev->dn_
  315. XStartup);
  316. X    ULONG *env = (ULONG *)BADDR(fmsg->fssm_Environ);
  317. X    int quit, bit;
  318. X    struct IntuiMessage *msg;
  319. X    long first, last, numblks, pos, i, blk, word, x, y;
  320. X    int firstx, firsty, lastx, lasty;
  321. X
  322. X    if (prepare_window(dev))
  323. X    {
  324. X        if (!ReadBlock(secbuf, root_blk)) goto diskerror;
  325. X        first = blk_size - 49; last = blk_size - 24; /* extent of bitmap list *
  326. X/
  327. X        numblks = env[DE_NUMHEADS] * env[DE_BLKSPERTRACK] * (env[DE_UPPERCYL] -
  328. X env[DE_LOWCYL] + 1);
  329. X        blk = env[DE_RESERVEDBLKS]; /* First block described in bitmap */
  330. X        pos = first;
  331. X        lasty = -recth - 1; firsty = -1;
  332. X
  333. X        do {
  334. X            if (pos == last) /* End of bitmap table list, read extension bitmap
  335. X table */
  336. X            {
  337. X                if (!ReadBlock(secbuf, secbuf[last])) goto diskerror;
  338. X                pos = first = 0;
  339. X                last = blk_size - 1;
  340. X            }
  341. X            /* Read next bitmap sector */
  342. X            if (!ReadBlock(secbuf2, secbuf[pos++])) goto diskerror;
  343. X
  344. X            /* Display free blocks in it */
  345. X            for (i = 1; blk != numblks && i < blk_size; i++)
  346. X            {
  347. X                word = secbuf2[i];
  348. X                for (bit = 0; blk != numblks && bit < 32; bit++, blk++)
  349. X                {
  350. X                    if (word & 1) /* Free sector */
  351. X                    {
  352. X                        cvt_point(&x, &y, blk);
  353. X                        /* Speed up drawing (by a factor of 3 on HD), check
  354. X                           for consecutive free blocks & draw them in one go */
  355. X     
  356. X                        if (y != lasty + recth || x != lastx)
  357. X                        {
  358. X                            /* Non consecutive blocks, draw */
  359. X
  360. X                            if (firsty != -1)
  361. X                                RectFill(win->RPort, firstx, firsty, lastx + re
  362. Xctw - 1, lasty + recth - 1);
  363. X                            firstx = x; firsty = y;
  364. X                        }
  365. X                        lastx = x; lasty = y;
  366. X                    }
  367. X                    word >>= 1; /* next sector */
  368. X                }
  369. X            }
  370. X        } while (blk != numblks);
  371. X        if (firsty != -1)
  372. X            RectFill(win->RPort, firstx, firsty, lastx + rectw - 1, lasty + rec
  373. Xth - 1);
  374. X        Motor(FALSE); /* Turn drive motor off */
  375. X
  376. X        quit = FALSE;
  377. X        while (!quit)
  378. X        {
  379. X            WaitPort(win->UserPort);
  380. X            while (msg = (struct IntuiMessage *)GetMsg(win->UserPort))
  381. X            {
  382. X                quit = msg->Class == CLOSEWINDOW;
  383. X                ReplyMsg((struct Message *)msg);
  384. X            }
  385. X        }
  386. X        CloseWindow(win);
  387. X    }
  388. X    else error("Couldn't open window\n");
  389. X    return;
  390. X
  391. Xdiskerror:
  392. X    CloseWindow(win);
  393. X    error("Error reading disk\n");
  394. X}
  395. X
  396. X/* Display free blocks on partition passed as parm, from CLI only */
  397. Xvoid main(int argc, char **argv)
  398. X{
  399. X    struct DeviceNode *dev;
  400. X
  401. X    cli = (argc != 0);
  402. X
  403. X    if (IntuitionBase = (struct IntuitionBase *)OpenLibrary("intuition.library"
  404. X, 0L))
  405. X        if (GfxBase = (struct GfxBase *)OpenLibrary("graphics.library", 0L))
  406. X            if (argc != 2) error("Usage: free <device>\n")
  407. X            else
  408. X            {
  409. X                int l = strlen(argv[1]) - 1;
  410. X
  411. X                if (argv[1][l] != ':') error("Not a device spec!\n")
  412. X                else
  413. X                {
  414. X                    argv[1][l] = '\0';
  415. X                    dev = FindDevice(argv[1]);
  416. X                    if (dev)
  417. X                    {
  418. X                        if (setup(dev)) disp_free(dev);
  419. X                        release();
  420. X                    }
  421. X                    else error("No such device\n");
  422. X                }
  423. X            }
  424. X        else error("No graphics library !\n")
  425. X    else error("No intuition library !\n");
  426. X
  427. X    if (IntuitionBase) CloseLibrary((struct Library *)IntuitionBase);
  428. X    if (GfxBase) CloseLibrary((struct Library *)GfxBase);
  429. X    if (_Backstdout) Close(_Backstdout);
  430. X}
  431. SHAR_EOF
  432. echo "extracting free.doc"
  433. sed 's/^X//' << \SHAR_EOF > free.doc
  434. X    This is a small program to graphically dsplay the free blocks on a disk
  435. X(you can thus see how fragmented it is).
  436. X
  437. XUsage
  438. X-----
  439. X
  440. X    This program runs from the CLI only:
  441. X
  442. X        free <device name>:
  443. X
  444. X        will display the free blocks on the disk in the device specified
  445. X        (you must specify the device, not the name of the disk).
  446. X        Note that this program detaches from the CLI, don't 'RUN' it !
  447. X
  448. X        Example:
  449. X
  450. X            free df0:
  451. X
  452. X    The window opened will be a representation of the disk, with cylinders
  453. X    presented vertically (if possible). The lit pixels represent the free
  454. X    blocks on the disk.
  455. X
  456. X
  457. XDistribution
  458. X------------
  459. X
  460. X    This software is placed in the public domain.
  461. X
  462. X
  463. X~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  464. XDavid Gay
  465. X  "(p.suiv :=: q.prec.suiv).prec :=: q.prec"
  466. X  You don't want to know about this language !
  467. X
  468. XGAY_D@ELMA.EPFL.CH, or GAY_D%ELMA.EPFL.CH@CLSEPF51.bitnet
  469. X(till mid-august 89)
  470. X
  471. X~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  472. X
  473. X
  474. SHAR_EOF
  475. echo "extracting free.hdr"
  476. sed 's/^X//' << \SHAR_EOF > free.hdr
  477. XFrom dg3i+@andrew.cmu.edu Sat Nov 11 18:44:13 1989
  478. XDate: Fri, 10 Nov 89 16:08:45 -0500 (EST)
  479. XFrom: David Gay <dg3i+@andrew.cmu.edu>
  480. XTo: page@Sun.COM
  481. XSubject: comp.sources.amiga submission, show disk space
  482. X
  483. X#       This is a shell archive.
  484. X#       Remove everything above and including the cut line.
  485. X#       Then run the rest of the file through sh.
  486. SHAR_EOF
  487. echo "extracting free.uu"
  488. sed 's/^X//' << \SHAR_EOF > free.uu
  489. X
  490. Xbegin 644 free
  491. XM```#\P`````````#``````````(```#*```#0@```-8```/I````RDCG?OY+,
  492. XM[P`T)$@D`$GY`````"QX``0I3@!:*4\`8D*L`%Y'^0```K1R`"`\````*6`"C
  493. XM)L%1R/_\)FX!%'``(CP``#``3J[^SBEK`)@`5DJK`*QG``%080`"G"(L`%8L4
  494. XM;`-(3J[_H"E``%8@:P"LT<C1R")H`!#3R=/)(`)R`!(9*`DF`=*!T(%:@.6(.
  495. XMT*P`%"E``!1![```+'@`!$ZN_R(B0"\`(FD`$$?I`.8@1"`#8`(6V%'(__P6"
  496. XM_``@($H@`F`"%MA1R/_\0ALI2P!V($0@`V`"%MA1R/_\0A-%Z0!L*4H`&D7ZY
  497. XM_Q8B_````#DF">2+(M)"DD7Z`38@/````-T2VE'(__Q*K`">9P``&D'L`(8BK
  498. XM""0\```#[2QL`TA.KO_B*4``<BQX``1.KO]\(BP`EB0L`)HH+`"(+&P#2$ZN;
  499. XM_W8F3DJ`9@``("1?(FH`$"(L`%9.KO^F($HL>``$3J[_''!H8```)B1`(E]%.
  500. XMZO^D0>H`2D'H``0@*``$(4D`!"*((T``!"!`((EP`"QX``1.KO]V(DLL>``$A
  501. XM3J[^8DS??WY.=2EK`#H`)@:L````@``F80`!0$7Z`/`I2@`:80`!3"E``%XO5
  502. XM`"1`("H`)&<2+&P#2"!`(B@``"E!`%9.KO^"(BH`(&<:)#P```/M3J[_XBE`8
  503. XM`&YG"N6(($`G:``(`*0@;`!>+PA(;``B(&@`)"EH``0`=DZZ`0A.N0``#,QPU
  504. XM`&```(0````Y`````"`/2.=^_BI`+'@`!$GY`````"E/`&)A``"ND\DL>``$X
  505. XM3J[^VB9`*6L`.@`F!JP```"``"8@:P"`T<C1R")H``S3R=/)*5$`'B%1``PB)
  506. XM+`!6+&P#2$ZN_X)(>@"$3KD```S,6$\B+``>+&P#2$ZN_V0B+`!63J[_IG``1
  507. XM("P`3F<$($!.D$ZY```,Q"QX``0B;`-(3J[^8DZY```)3DJL`%YG&B(L`&YG-
  508. XM!$ZN_]PL>``$3J[_?")L`%Y.KOZ&+FP`8DS??WY.=4/L`'IP`$ZN_=@I0`-(K
  509. XM9P``!$YU<&1@G$'K`%Q.KOZ`0>L`7$ZN_HQ.=0``3OD```E,<&$```/L````M
  510. XM!0````$```+&```"M````HP```(<```#(@````,````"````)````CP````.*
  511. XM`````````_(```/I```#0DY5__0O"BM`__CE@")`1>D``1(12(%(P2]```0K@
  512. XM2/_\(`$B2DZZ"EX@;P`$$!!(@"!M__Q",```(`@D7TY=3G5.5?_P*T#_]"`L*
  513. XM`R@B+`,X3KH*QB]````@+?_T(B\``$ZZ"M8B+`,L3KH*KE2`((`@+?_T(BP#V
  514. XM.$ZZ"KX@+`,P3KH*EG(*T($B@$Y=3G5.5?_X2.<S$B9(("L`'.6`($`B*``(&
  515. XMY8$@02`H``PB*``43KH*9BX`("@`*)"H`"0L`%*&<$)&`+Z`;B8I1P,X(`8BL
  516. XM/````GQ.N@I@4H`I0`,H(`8B+`,H3KH*4"E``S1@.BE``S@@!B('3KH*'G)"D
  517. XM1@%.N@HV4H`B/````GPO0``83KH*)E*`*4`#*"`O`!@B+`,H3KH*%"E``S1PX
  518. XM9-"`(BP#-$ZZ"@12@"E``RQP4"(L`SA.N@GT4H`I0`,P("L`*$'L`K1A`/ZJ4
  519. XM0>P"M$/L`-).N@DZ0>P"M"E(`+P@+`,L(BP#-$ZZ":)8@#E``*8@+`,P(BP#Y
  520. XM.$ZZ"9!R"]"!.4``J$'L`*(L;`-`3J[_-"E``R1*@&=2($`B:``R<`(L;`-$A
  521. XM3J[^JB!L`R0P*``(2,!7@#(H``I(P56!+T``&"]!`!PB:``R<`)R"B0O`!@FG
  522. XM+P`<3J[^SB!L`R0B:``R<`-.KOZJ<`%@`G``3-](S$Y=3G5.5?_X2.<`$B9(2
  523. XM(&P#"#%\``(`'"%!`"0A2P`H(&P#""%``"PK0/_X*T'__")(+'@`!$ZN_C@@-
  524. XM;`,($"@`'TH`9@0@2V`"D<@@"$S?2`!.74YU3E7__"\.(&P#"#%\``D`'"%`6
  525. XM`"0K0/_\(D@L>``$3J[^."Q?3EU.=4CG`3(F2"!+2AAF_%.(D<LN""QX``1.I
  526. XMKO]\(&P#2"!H`"(@*``8Y8`@0"(H``3E@21!8"Y*J@`$9B(@*@`HY8`@0!(0/
  527. XM2(%(P;*'9A!#Z``!(`<@2TZZ!TY*@&<*(!+E@"1`(`IFSBQX``1.KO]V(`I,_
  528. XMWTR`3G5(YP`R)D@L>``$3J[_?"!L`T@@:``B("@`&.6`($`B*``$Y8$D06`>9
  529. XM2JH`!&82M^H`"&8,+'@`!$ZN_W8@"F`4(!+E@"1`(`IFWBQX``1.KO]V<`!,`
  530. XMWTP`3G5.5?_X(BP#%-*`*T#_^"`L`Q!.N@>XY8`B+`,0Y8$K2/_\80#^DDY=]
  531. XM3G5.5?_82.<P,B9(("L`'.6`)D`@*P`(Y8`D0'``D<A.N@BB*4`#!&8B2JP#V
  532. XM/&<6<`DB+`!R0>P`XB0()@`L;`-(3J[_T'``8``!%B!L`P1.N@@V*4`#"$J`_
  533. XM9BA*K`,\9QQR#R]!`!0B+`!R0>P`]B0()B\`%"QL`TA.KO_0<`!@``#>("L`J
  534. XM!$'M_]QA`/O^($`@$R)L`P@B*P`,+'@`!$ZN_D1*@&<B2JP#/&<6<!(B+`!R9
  535. XM0>P!%B0()@`L;`-(3J[_T'``8```F'`!*4`##"(J``0I00,0("H`)"(J`!1.^
  536. XMN@;"(BH`#$ZZ!KHI0`,4("H`%"(J``Q.N@:J(BH`*)*J`"12@4ZZ!IS0J@`8S
  537. XM4X#BB"E``Q@@+`,0YX`B*@`P+'@`!$ZN_SHI0`,<9B!*K`,\9Q9P$B(L`')!C
  538. XM[`$^)`@F`"QL`TA.KO_0<`!@$B`L`Q#E@"!L`QS1P"E(`R!P`4S?3`Q.74YU#
  539. XM+PY*K`,<9Q(@+`,0YX`B;`,<+'@`!$ZN_RY*K`,,9PPB;`,(+'@`!$ZN_CY**
  540. XMK`,(9P@@;`,(3KH%F$JL`P1G""!L`P1.N@6V+%].=4Y5_\!(YS\R)D@@2R`H5
  541. XM`!SE@")`(BD`".6!)D%A`/M(2H!G``(N("P#&"!L`QQA`/WT2H!G``(Z>NC:5
  542. XMK`,0*T7_["`K``PB*P`43KH%I"(K`"B2JP`D4H%.N@66*"L`&'S/W*P#$"M&1
  543. XM_^@B+`,P1($N`5.'<O\K0?_4+T``)+R%9B0@!>6`(&P#'")(T\`@$6$`_9)*A
  544. XM@&<``=A\`"`L`Q!3@"M`_^P@!E*`(@;E@2!L`QS1P2M`_^@@$"!L`R!A`/UDZ
  545. XM2H!G``&J>@%\!&```+H@;`,@T>W_S"P0>@!@``"0"`8``&<``((@!$'M_^!#Z
  546. XM[?_<80#Z)-ZL`S`@+?_<L(=F#"`M_]`B+?_@LH!G4"`M_]1R_["!9S8B+?_0%
  547. XMTJP#+%.!)`=3@B]!`"@@;`,D(F@`,B`M_]@B+?_4+T(`+"0O`"@F+P`L+&P#"
  548. XM1$ZN_LX@+?_@(BW_W"M`_]@K0?_4*VW_X/_0+BW_W.*&4H52A+BO`"1G"'`@^
  549. XMNH!M`/]F*BW_Y%*%+"W_S%B&*T7_Y"M&_\PL+P`DN(9G"+JL`Q!M`/\R(`8J!
  550. XM+?_L+"W_Z+B`9@#^T"PM_]1P_[R`9S@@+?_0T*P#+%.`(@?2K`,P4X$O0``D5
  551. XM+T$`*"!L`R0B:``R("W_V"(&)"\`)"8O`"@L;`-$3J[^SG``80#[-GX`8$0@R
  552. XM;`,D(&@`5BQX``1.KOZ`8!P,JP```@``%%?`1`!(@$C`+@`B2RQX``1.KOZ&*
  553. XM(&P#)"!H`%8L>``$3J[^C"9`(`MFSDJ'9[@@;`,D+&P#0$ZN_[A@1DJL`SQGW
  554. XM0'`5(BP`<D'L`68D""8`+&P#2$ZN_]!@*"!L`R0L;`-`3J[_N$JL`SQG%G`37
  555. XM(BP`<D'L`9(D""8`+&P#2$ZN_]!,WTS\3EU.=4Y5__Q(YS$R+@`F2$J'5L!$8
  556. XM`$B`2,`I0`,\0^P!NG``+'@`!$ZN_=@I0`-`2H!G``#T0^P!S'``3J[]V"E`"
  557. XM`T1*@&<``+QR`KZ!9RA*K`,\9P``]'(5+T$`&"(L`')![`'>)`@F+P`8+&P#5
  558. XM2$ZN_]!@``#4(&L`!$H89OQ3B)'K``0B"%.!(&L`!-'!)$AR.K(29RA*K`,\T
  559. XM9P``K'(3+T$`&"(L`')![`(*)`@F+P`8+&P#2$ZN_]!@``",0A(@:P`$80#Y)
  560. XM\"9`(`MG%B!+80#ZWDJ`9P8@2V$`_(9A`/PV8&1*K`,\9UYP#R(L`')![`(R8
  561. XM)`@F`"QL`TA.KO_08$9*K`,\9T!R%B]!`!@B+`!R0>P"4B0()B\`&"QL`TA.=
  562. XMKO_08")*K`,\9QQR%R]!`!@B+`!R0>P"@B0()B\`&"QL`TA.KO_02JP#0&<,L
  563. XM(FP#0"QX``1.KOYB2JP#1&<,(FP#1"QX``1.KOYB2JP`<F<,(BP`<BQL`TA.J
  564. XMKO_<3-],C$Y=3G5.=4YU#```86T*#```>FX$!```($YU``!.5?]T2.<!,"9(G
  565. XM?@!P(+Z`;'H0$W(@L`%G#'()L`%G!G(*L`%F!%*+8.A*$V=>(`?E@%*'0>W_4
  566. XM=-'`)$AP(K`39B)2BR2+2A-G"G`BL!-G!%*+8/)*$V8(<`%.N@!48*Q"&V"H@
  567. XM)(M*$V<8$!-R(+`!9Q!R";`!9PIR"K`!9P12BV#D2A-F`F`$0AM@@$J'9P9!C
  568. XM[?]T8`0@;`!>(`=.NOW&<`!.N@`,3-\,@$Y=3G4``$[Y````&````````$Y5+
  569. XM__Q(YP,P)D@D22X`2H=G,DH39RY*$F<J<``0&TZZ_Q!R`!(:+T``$"`!3KK_F
  570. XM`B(O`!"2@"P!2H9G!"`&8!I3AV#*2H=G$$H39P1P`6`*2A)G!'#_8`)P`$S??
  571. XM#,!.74YU```B"&`$$-EG"%.`9/A@!D(84X!D^B`!3G4@"$H89OQ3B!#99OQ.$
  572. XM=0``2.<`$B9(%WP`_P`(,'S__R=(`!0G2``8(DMP,"QX``1.KO\N3-](`$YU&
  573. XM``!(YP`2)DA*JP`*9PHB2RQX``1.KOZ8%WP`_P`(</\G0``4<``0*P`/+'@`H
  574. XM!$ZN_K`B2W`B3J[_+DS?2`!.=0``2.<P`"0`)@%(0DA#Q,'&P,#!U$-(0D)"\
  575. XMT(),WP`,3G5*@&H``!Y$@$J!:@``#$2!80``($2!3G5A```81(!$@4YU2H%JK
  576. XM```,1(%A```&1(!.=2\"2$$T`68``")(0$A!2$(T`&<```:$P3`"2$`T`(3!J
  577. XM,`)(0C(")!].=2\#=A`,00"`9```!N&944,,00@`9```!NF964,,02``9```A
  578. XM!N6954-*06L```;CF5-#-`#FJ$A"0D+FJDA#@,$V`#`"-`-(0<3!D()D```(!
  579. XM4T/0@63^<@`R`TA#Y[A(0,%!)A\D'TYU2.<`,B9((`MF!'``8"9P,"(\``$`(
  580. XM`2QX``1.KO\Z)$`@"F<.%7P`!0`(0BH`"25+``X@"DS?3`!.=0``2.<#,B9(H
  581. XM+@!P_RQX``1.KOZV+``,!@#_9@1P`&!F<"(B/``!``%.KO\Z)$`@"F8*<``0W
  582. XM!DZN_K!@2"5+``H@!Q5```D5?``$``A"*@`.%48`#Y/)3J[^VB5``!`@"V<(7
  583. XM(DI.KOZ>8!I!Z@`8)4@`%$'J`!0E2``<0JH`&!5\``(`("`*3-],P$YU``!@%
  584. XM```23G$``"!O``1@`/R23G$``$CG`#(F;`-,(`MG%"13(DL@*P`(+'@`!$ZN4
  585. XM_RXF2F#HD<@I2`-0*4@#3$S?3`!.=0```^P````!`````@``"A8````````#1
  586. XM\@```^H```"M`````````````````````0````$```#F3OD`````````````[
  587. XM`````````````````````````````````````````````````````````````
  588. XM``````````````````````````````````````````````````````!D;W,NT
  589. XM;&EB<F%R>0`J````!]!F<F5E8FQK<P``````C``````````!``````````#_0
  590. XM_P```@```P`.```````````````````````````````````````!.BP@9G)E6
  591. XM92!B;&]C:W,``$YO('!O<G0A"@!.;R!P;W)T(0H`3F\@24\@<F5Q=65S="$*F
  592. XM`$YO($E/(')E<75E<W0A"@!$979I8V4@;F]T(&]P96YE9`H``$1E=FEC92!N-
  593. XM;W0@;W!E;F5D"@``3F\@<V5C=&]R(&)U9F9E<B$*``!.;R!S96-T;W(@8G5F$
  594. XM9F5R(0H``$-O=6QD;B=T(&]P96X@=VEN9&]W"@!#;W5L9&XG="!O<&5N('=I.
  595. XM;F1O=PH`17)R;W(@<F5A9&EN9R!D:7-K"@!%<G)O<B!R96%D:6YG(&1I<VL*T
  596. XM`&EN='5I=&EO;BYL:6)R87)Y`&=R87!H:6-S+FQI8G)A<GD``%5S86=E.B!FO
  597. XM<F5E(#QD979I8V4^"@!5<V%G93H@9G)E92`\9&5V:6-E/@H`3F]T(&$@9&5VF
  598. XM:6-E('-P96,A"@!.;W0@82!D979I8V4@<W!E8R$*`$YO('-U8V@@9&5V:6-E_
  599. XM"@!.;R!S=6-H(&1E=FEC90H`3F\@9W)A<&AI8W,@;&EB<F%R>2`A"@``3F\@?
  600. XM9W)A<&AI8W,@;&EB<F%R>2`A"@``3F\@:6YT=6ET:6]N(&QI8G)A<GD@(0H`1
  601. XM3F\@:6YT=6ET:6]N(&QI8G)A<GD@(0H```````/L`````0````(```"6````H
  602. X%`````_)TI
  603. X``
  604. Xend
  605. Xsize 5000
  606. SHAR_EOF
  607. echo "extracting blocks.c"
  608. sed 's/^X//' << \SHAR_EOF > blocks.c
  609. X#include <exec/types.h>
  610. X#include <exec/io.h>
  611. X#include <libraries/dos.h>
  612. X#include <libraries/dosextens.h>
  613. X#include <libraries/filehandler.h>
  614. X#include <intuition/intuition.h>
  615. X#include <workbench/startup.h>
  616. X
  617. X#include <proto/exec.h>
  618. X#include <proto/dos.h>
  619. X#include <proto/graphics.h>
  620. X#include <proto/intuition.h>
  621. X
  622. X#include <stdio.h>
  623. X#include <string.h>
  624. X
  625. X#define error(s) { if (cli) Write(_Backstdout, (s), strlen(s)); }
  626. X
  627. X#define USAGE "blocks <filename>\n"
  628. X/* border sizes */
  629. X#define XLEFT 2
  630. X#define XRIGHT 2
  631. X#define YTOP 10
  632. X#define YBOTTOM 1
  633. X/* Min & Max size for window */
  634. X#define MAXHEIGHT (200 - YTOP - YBOTTOM)
  635. X#define MAXWIDTH   (640 - XLEFT - XRIGHT)
  636. X#define MINWIDTH 200
  637. X#define MINHEIGHT 80
  638. X
  639. X/* Spawn info */
  640. Xlong _stack = 2000;
  641. Xchar *_procname = "blocks";
  642. Xlong _priority = 0;
  643. Xlong _BackGroundIO = TRUE;
  644. Xextern long _Backstdout;
  645. X
  646. Xtypedef struct FileInfoBlock FIB;
  647. Xtypedef struct InfoData INFO;
  648. X
  649. Xextern struct IntuitionBase *IntuitionBase;
  650. Xextern struct GfxBase *GfxBase;
  651. X
  652. X/* For io to device */
  653. Xstruct MsgPort *port;
  654. Xstruct IOStdReq *io;
  655. Xint DevOpen;
  656. X/* Device info */
  657. Xlong blk_size, blk_offset, root_blk, *secbuf;
  658. Xstruct Window *win;
  659. X/* size of window, of each block, etc */
  660. Xint xdiv, rectw, recth, width, height;
  661. Xint cli; /* Called from cli ? */
  662. X
  663. Xstruct NewWindow newwin = {
  664. X    0, 0,
  665. X    0, 0,
  666. X    -1, -1,
  667. X    CLOSEWINDOW,
  668. X    WINDOWDRAG | WINDOWDEPTH | WINDOWCLOSE | SMART_REFRESH | NOCAREREFRESH | RM
  669. XBTRAP,
  670. X    NULL,
  671. X    NULL,
  672. X    NULL,
  673. X    NULL,
  674. X    NULL,
  675. X    0, 0, 0, 0,
  676. X    WBENCHSCREEN
  677. X};
  678. X
  679. X/* Calculate coords on window for block 'block' on disk */
  680. Xvoid cvt_point(x, y, block)
  681. Xlong *x, *y, block;
  682. X{
  683. X    *x = rectw * (block / (xdiv * height)) + XLEFT;
  684. X    *y = recth * (block % height) + YTOP;
  685. X}
  686. X
  687. X/* Calc size, & open window */
  688. Xint prepare_window(fib, dev)
  689. Xstruct FileInfoBlock *fib;
  690. Xstruct DeviceNode *dev;
  691. X{
  692. X    /* Get disk characteristics */
  693. X    struct FileSysStartupMsg *msg = (struct FileSysStartupMsg *)BADDR(dev->dn_S
  694. Xtartup);
  695. X    ULONG *env = (ULONG *)BADDR(msg->fssm_Environ);
  696. X    long blkscyl = env[DE_NUMHEADS] * env[DE_BLKSPERTRACK];
  697. X    long numcyls = env[DE_UPPERCYL] - env[DE_LOWCYL] + 1;
  698. X    long blks;
  699. X    static char title[80];
  700. X
  701. X    if (blkscyl <= MAXHEIGHT) /* Do a "nice" presentation, 1 cylinder per vert
  702. Xline */
  703. X    {
  704. X        height = blkscyl;
  705. X        xdiv = (numcyls / MAXWIDTH + 1); /* Nb of cylinders per vertical line *
  706. X/
  707. X        width = numcyls / xdiv;
  708. X    }
  709. X    else /* Just squash em in */
  710. X    {
  711. X        blks = numcyls * blkscyl;
  712. X        height = MAXHEIGHT;
  713. X        xdiv = (blks / MAXHEIGHT + 1) / MAXWIDTH + 1;
  714. X        width = (blks / MAXHEIGHT + 1) / xdiv;
  715. X    }
  716. X    /* Size of rect for 1 block */
  717. X    rectw = MINWIDTH / width + 1;
  718. X    recth = MINHEIGHT / height + 1;
  719. X
  720. X    /* Open window */
  721. X    sprintf(title, "File: %s, %ld blocks", fib->fib_FileName, fib->fib_NumBlock
  722. Xs);
  723. X    newwin.Title = title;
  724. X    newwin.Width = rectw * width + XLEFT + XRIGHT;
  725. X    newwin.Height = recth * height + YTOP + YBOTTOM;
  726. X
  727. X    if (win = OpenWindow(&newwin))
  728. X    {
  729. X        SetAPen(win->RPort, 2);
  730. X        RectFill(win->RPort, XLEFT, YTOP, win->Width - XRIGHT - 1, win->Height
  731. X- YBOTTOM - 1);
  732. X        SetAPen(win->RPort, 3);
  733. X        return TRUE;
  734. X    }
  735. X    return FALSE;
  736. X}
  737. X
  738. X/* bstr -> cstr */
  739. Xchar *btoc_str(to, from)
  740. Xchar *to;
  741. XBSTR from;
  742. X{
  743. X    char *cstr = (char *)BADDR(from);
  744. X
  745. X    strncpy(to, cstr + 1, *cstr);
  746. X    to[*cstr] = '\0';
  747. X
  748. X    return to;
  749. X}
  750. X
  751. X/* Reads sector at offset 'sector' from disk ('sector' must be a multiple of 51
  752. X2) */
  753. XBYTE *ReadSector(sector, buf, len)
  754. Xlong sector;
  755. XBYTE *buf;
  756. Xlong len;
  757. X{
  758. X    io->io_Command = CMD_READ;
  759. X    io->io_Length = len;
  760. X    io->io_Data = (APTR)buf;
  761. X    io->io_Offset = sector;
  762. X    DoIO((struct IORequest *)io);
  763. X    return (io->io_Error == 0) ? buf : NULL;
  764. X}
  765. X
  766. X/* Find device by task */
  767. Xstruct DeviceNode *TaskDevice(task)
  768. Xstruct MsgPort *task;
  769. X{
  770. X    struct DeviceNode *devlist;
  771. X
  772. X    Forbid();
  773. X    devlist = (struct DeviceNode *)BADDR(((struct DosInfo *)BADDR(((struct Root
  774. XNode *)(DOSBase->dl_Root))->rn_Info))->di_DevInfo);
  775. X    for (;devlist; devlist = (struct DeviceNode *)BADDR(devlist->dn_Next))
  776. X        if (devlist->dn_Type == DLT_DEVICE)
  777. X        {
  778. X            if (task == devlist->dn_Task) { Permit(); return devlist; }
  779. X        }
  780. X
  781. X    Permit();
  782. X    return NULL;
  783. X}
  784. X
  785. X/* Reads block n of *partition* */
  786. Xvoid ReadBlock(n)
  787. Xlong n;
  788. X{
  789. X    ReadSector((blk_offset + n) * blk_size * 4, secbuf, blk_size * 4);
  790. X}
  791. X
  792. X/* Get partition characteristics, open device */
  793. Xint setup(dev)
  794. Xstruct DeviceNode *dev;
  795. X{
  796. X    char devname[32];
  797. X    struct FileSysStartupMsg *msg = (struct FileSysStartupMsg *)BADDR(dev->dn_S
  798. Xtartup);
  799. X    ULONG *env = (ULONG *)BADDR(msg->fssm_Environ);
  800. X    long err;
  801. X
  802. X    port = CreatePort(0, 0);
  803. X    if (!port)
  804. X    {
  805. X        error("No port!\n");
  806. X        return FALSE;
  807. X    }
  808. X    io = CreateStdIO(port);
  809. X    if (!io)
  810. X    {
  811. X        error("No IO request!\n");
  812. X        return FALSE;
  813. X    }
  814. X    err = OpenDevice(btoc_str(devname, msg->fssm_Device), msg->fssm_Unit, (stru
  815. Xct IORequest *)io, msg->fssm_Flags);
  816. X    if (err)
  817. X    {
  818. X        error("Device not opened\n");
  819. X        return FALSE;
  820. X    }
  821. X    DevOpen = TRUE;
  822. X    blk_size = env[DE_SIZEBLOCK];
  823. X    blk_offset = env[DE_LOWCYL] * env[DE_BLKSPERTRACK] * env[DE_NUMHEADS];
  824. X    root_blk = (env[DE_BLKSPERTRACK] * env[DE_NUMHEADS] * (env[DE_UPPERCYL] - e
  825. Xnv[DE_LOWCYL] + 1) - 1 + env[DE_RESERVEDBLKS]) / 2;
  826. X    secbuf = (long *)AllocMem(4 * blk_size, env[DE_MEMBUFTYPE]);
  827. X    if (!secbuf)
  828. X    {
  829. X        error("No sector buffer!\n");
  830. X        return FALSE;
  831. X    }
  832. X    return TRUE;
  833. X}
  834. X
  835. X/* Close device */
  836. Xvoid release()
  837. X{
  838. X    if (secbuf) FreeMem((char *)secbuf, 4 * blk_size);
  839. X    if (DevOpen) CloseDevice((struct IORequest *)io);
  840. X    if (io) DeleteStdIO(io);
  841. X    if (port) DeletePort(port);
  842. X}
  843. X
  844. X/* Displays blocks used by file described by fib */
  845. X/* For OFS/FFS !!! */
  846. Xvoid get_blocks(fib, node, device)
  847. XFIB *fib;
  848. Xstruct DeviceList *node;
  849. Xstruct DeviceNode *device;
  850. X{
  851. X    long key = fib->fib_DiskKey, data1 = blk_size - 51, used, i, x, y;
  852. X    int quit;
  853. X    struct IntuiMessage *msg;
  854. X
  855. X    if (prepare_window(fib, device))
  856. X    {
  857. X        do {
  858. X            Forbid();
  859. X            if (device->dn_Task != node->dl_Task)
  860. X            {
  861. X                error("Disk not in drive!\n");
  862. X                break;
  863. X            }
  864. X            ReadBlock(key); /* Read either File header or file list block */
  865. X            Permit();
  866. X            used = secbuf[2]; /* num blocks described here */
  867. X            /* Draw blocks */
  868. X            for (i = 0; i < used; i++)
  869. X            {
  870. X                cvt_point(&x, &y, secbuf[data1 - i]);
  871. X                RectFill(win->RPort, x, y, x + rectw - 1, y + recth - 1);
  872. X            }
  873. X            /* Extension blocks ? */
  874. X            key = secbuf[blk_size - 2];
  875. X        } while (key != 0);
  876. X
  877. X        /* Wait for window close */
  878. X        quit = FALSE;
  879. X        while (!quit)
  880. X        {
  881. X            WaitPort(win->UserPort);
  882. X            while (msg = (struct IntuiMessage *)GetMsg(win->UserPort))
  883. X            {
  884. X                quit = msg->Class == CLOSEWINDOW;
  885. X                ReplyMsg((struct Message *)msg);
  886. X            }
  887. X        }
  888. X        CloseWindow(win);
  889. X    }
  890. X}
  891. X
  892. X/* Display blocks used by file name */
  893. Xvoid disp_blocks(name)
  894. Xchar *name;
  895. X{
  896. X    FIB *fib = (FIB *)AllocMem(sizeof(FIB), 0L);
  897. X    INFO *info = (INFO *)AllocMem(sizeof(INFO), 0L);
  898. X    BPTR lock = Lock(name, SHARED_LOCK);
  899. X    struct DeviceList *node;
  900. X    struct DeviceNode *device;
  901. X
  902. X    if (fib && info)
  903. X        if (lock)
  904. X            if (Info(lock, info) && Examine(lock, fib))
  905. X                if (fib->fib_DirEntryType >= 0) error("Only for files!\n")
  906. X                else if (info->id_UnitNumber < 0) error("Only on OFS or FFS dis
  907. Xks\n") /* Test detects RAM: ... */
  908. X                else
  909. X                {
  910. X                    node = (struct DeviceList *)BADDR(info->id_VolumeNode);
  911. X                    if (node == 0) error("Disk not in drive\n")
  912. X                    else
  913. X                        if (device = TaskDevice(node->dl_Task))
  914. X                        {
  915. X                            if (setup(device)) get_blocks(fib, node, device);
  916. X                            release();
  917. X                        }
  918. X                        else error("Couldn't find disk's device!\n")
  919. X                }
  920. X            else error("Couldn't get info on file\n")
  921. X        else error("No such file\n")
  922. X    else error("No memory !\n");
  923. X
  924. X    if (lock) UnLock(lock);
  925. X    if (fib) FreeMem((char *)fib, sizeof(FIB));
  926. X    if (info) FreeMem((char *)info, sizeof(INFO));
  927. X}
  928. X
  929. X/* Display blocks used by files passed as parms
  930. X   Works from WB or CLI */
  931. Xvoid main(argc, argv)
  932. Xint argc;
  933. Xchar **argv;
  934. X{
  935. X    int i;
  936. X
  937. X    cli = (argc != 0);
  938. X
  939. X    if (IntuitionBase = (struct IntuitionBase *)OpenLibrary("intuition.library"
  940. X, 0L))
  941. X        if (GfxBase = (struct GfxBase *)OpenLibrary("graphics.library", 0L))
  942. X            if (argc == 0) /* WB */
  943. X            {
  944. X                struct WBStartup *msg = (struct WBStartup *)argv;
  945. X
  946. X                for (i = 1; i < msg->sm_NumArgs; i++)
  947. X                    if (msg->sm_ArgList[i].wa_Name[0] != '\0') /* A dir */
  948. X                    {
  949. X                        CurrentDir(msg->sm_ArgList[i].wa_Lock);
  950. X                        disp_blocks(msg->sm_ArgList[i].wa_Name);
  951. X                    }
  952. X            }
  953. X            else if (argc == 1) error(USAGE)
  954. X            else
  955. X                for (i = 1; i < argc; i++) disp_blocks(argv[i]);
  956. X        else error("No graphics library !\n")
  957. X    else error("No intuition library !\n");
  958. X
  959. X    if (IntuitionBase) CloseLibrary((struct Library *)IntuitionBase);
  960. X    if (GfxBase) CloseLibrary((struct Library *)GfxBase);
  961. X    if (_Backstdout) Close(_Backstdout);
  962. X}
  963. SHAR_EOF
  964. echo "extracting blocks.doc"
  965. sed 's/^X//' << \SHAR_EOF > blocks.doc
  966. X    This is a small program to graphically dsplay the blocks used by a file
  967. X(you can thus see how fragmented it is).
  968. X
  969. XUsage
  970. X-----
  971. X
  972. X    from the CLI:
  973. X
  974. X        blocks <file1> <file2> ...
  975. X
  976. X        will display the blocks used by file1, file2, ...
  977. X        Note that this program detaches from the CLI, don't 'RUN' it !
  978. X
  979. X    from the WB:
  980. X
  981. X        click on the icon for blocks (non provided, sorry!), then
  982. X        select the other icons of the files you want, double-clicking
  983. X        on the last one (you will have to hold the shift key down, of
  984. X        course).
  985. X
  986. X
  987. X    A window will be opened for the first file, when you close it, another
  988. X    one for the second file will appear, and so on.
  989. X
  990. X    The window opened will be a representation of the disk containing the
  991. X    file, with cylinders presented vertically (if possible). The lit
  992. X    pixels represent the blocks used by the file.
  993. X
  994. X
  995. XDistribution
  996. X------------
  997. X
  998. X    This software is placed in the public domain.
  999. X
  1000. X
  1001. X~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  1002. XDavid Gay
  1003. X  "(p.suiv :=: q.prec.suiv).prec :=: q.prec"
  1004. X  You don't want to know about this language !
  1005. X
  1006. XGAY_D@ELMA.EPFL.CH, or GAY_D%ELMA.EPFL.CH@CLSEPF51.bitnet
  1007. X(till mid-august 89)
  1008. X
  1009. X~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  1010. X
  1011. X
  1012. SHAR_EOF
  1013. echo "extracting blocks.uu"
  1014. sed 's/^X//' << \SHAR_EOF > blocks.uu
  1015. X
  1016. Xbegin 644 blocks
  1017. XM```#\P`````````#``````````(```#*```$>@```48```/I````RDCG?OY+V
  1018. XM[P`T)$@D`$GY`````"QX``0I3@!:*4\`8D*L`%Y'^0``!'!R`"`\````*F`"B
  1019. XM)L%1R/_\)FX!%'``(CP``#``3J[^SBEK`)@`5DJK`*QG``%080`"G"(L`%8L4
  1020. XM;`4(3J[_H"E``%8@:P"LT<C1R")H`!#3R=/)(`)R`!(9*`DF`=*!T(%:@.6(0
  1021. XMT*P`%"E``!1![```+'@`!$ZN_R(B0"\`(FD`$$?I`.8@1"`#8`(6V%'(__P6"
  1022. XM_``@($H@`F`"%MA1R/_\0ALI2P!V($0@`V`"%MA1R/_\0A-%Z0!L*4H`&D7ZY
  1023. XM_Q8B_````#DF">2+(M)"DD7Z`38@/````-T2VE'(__Q*K`"<9P``&D'L`(8BI
  1024. XM""0\```#[2QL!0A.KO_B*4``<BQX``1.KO]\(BP`E"0L`)@H+`"(+&P%"$ZN;
  1025. XM_W8F3DJ`9@``("1?(FH`$"(L`%9.KO^F($HL>``$3J[_''!H8```)B1`(E]%.
  1026. XMZO^D0>H`2D'H``0@*``$(4D`!"*((T``!"!`((EP`"QX``1.KO]V(DLL>``$A
  1027. XM3J[^8DS??WY.=2EK`#H`)@:L````@``F80`!0$7Z`/`I2@`:80`!3"E``%XO5
  1028. XM`"1`("H`)&<2+&P%""!`(B@``"E!`%9.KO^"(BH`(&<:)#P```/M3J[_XBE`:
  1029. XM`&YG"N6(($`G:``(`*0@;`!>+PA(;``B(&@`)"EH``0`=DZZ`0A.N0``#3!P:
  1030. XM`&```(0````Y`````"`/2.=^_BI`+'@`!$GY`````"E/`&)A``"ND\DL>``$X
  1031. XM3J[^VB9`*6L`.@`F!JP```"``"8@:P"`T<C1R")H``S3R=/)*5$`'B%1``PB)
  1032. XM+`!6+&P%"$ZN_X)(>@"$3KD```TP6$\B+``>+&P%"$ZN_V0B+`!63J[_IG``Z
  1033. XM("P`3F<$($!.D$ZY```1N"QX``0B;`4(3J[^8DZY```(UDJL`%YG&B(L`&YG/
  1034. XM!$ZN_]PL>``$3J[_?")L`%Y.KOZ&+FP`8DS??WY.=4/L`'IP`$ZN_=@I0`4(M
  1035. XM9P``!$YU<&1@G$'K`%Q.KOZ`0>L`7$ZN_HQ.=0``3OD```C4<&$```/L````T
  1036. XM!0````$```+&```"M````HP```(<```#(@````,````"````)````CP````.*
  1037. XM`````````_(```/I```$>DY5__P@+`3@(BP$\$ZZ#_HO0```("T`$"(O``!.K
  1038. XMNA`*(BP$Y$ZZ#^)4@"!M``@@@"`M`!`B+`3P3KH/[B`L!.A.N@_&<@K0@2!M?
  1039. XM``P@@$Y=3G5.5?_P2.<S`B!M``P@*``<Y8`@0"(H``CE@2!!("@`#"(H`!1.K
  1040. XMN@^0+@`@*``HD*@`)"P`4H9P0D8`OH!N)BE'!/`@!B(\```"?$ZZ#XI2@"E`C
  1041. XM!.`@!B(L!.!.N@]Z*4`$[&`Z*4`$\"`&(@=.N@](<D)&`4ZZ#V!2@"(\```"O
  1042. XM?"]``!1.N@]04H`I0`3@("\`%"(L!.!.N@\^*4`$['!DT(`B+`3L3KH/+E*`!
  1043. XM*4`$Y'!0(BP$\$ZZ#QY2@"E`!.@@;0`(4(@B;0`(+RD`@"\(2&P`T$AL!'!.\
  1044. XMN@XV3^\`$$'L!'`I2`"Z("P$Y"(L!.Q.N@[$6(`Y0`"D("P$Z"(L!/!.N@ZR;
  1045. XM<@O0@3E``*9![`"@+&P%`$ZN_S0I0`3<2H!G4B!`(F@`,G`"+&P%!$ZN_JH@%
  1046. XM;`3<,"@`"$C`5X`R*``*2,%5@2]``!0O00`8(F@`,G`"<@HD+P`4)B\`&$ZN3
  1047. XM_LX@;`3<(F@`,G`#3J[^JG`!8`)P`$S?0,Q.74YU3E7__"`M``SE@"!`0^@`:
  1048. XM`1(02(%(P2\!+PDO+0`(+T``#$ZZ#$@@;P`,$!!(@"!M``A",```(`A.74YUX
  1049. XM3E4``$CG`!(F;P`4(&P$Q#%\``(`'"%M`!``)"%+`"@@;`3$(6T`"``L(D@LN
  1050. XM>``$3J[^."!L!,00*``?2@!F!"!+8`*1R"`(3-](`$Y=3G5(YP`R)F\`$"QXF
  1051. XM``1.KO]\(&P%""!H`"(@*``8Y8`@0"(H``3E@21!8!Y*J@`$9A*WZ@`(9@PLQ
  1052. XM>``$3J[_=B`*8!0@$N6`)$`@"F;>+'@`!$ZN_W9P`$S?3`!.=4Y5```@+`30Z
  1053. XMT*T`""(L!,Q.N@T^Y8`B+`3,Y8$O`2\L!-@O`&$`_RY.74YU3E7_V$CG,#(FB
  1054. XM;P!$("L`'.6`)D`@*P`(Y8`D0$*G0J=.N@XB4$\I0`3`9B)*K`3T9Q9P"2(L1
  1055. XM`')![`#F)`@F`"QL!0A.KO_0<`!@``$*+RP$P$ZZ#;183RE`!,1*@&8H2JP$T
  1056. XM]&<<<@\O00`4(BP`<D'L`/HD""8O`!0L;`4(3J[_T'``8```T"\K``1(;?_<V
  1057. XM80#^6E!/($`@$R)L!,0B*P`,+'@`!$ZN_D1*@&<B2JP$]&<6<!(B+`!R0>P!N
  1058. XM&B0()@`L;`4(3J[_T'``8```B'`!*4`$R"(J``0I003,("H`)"(J`!1.N@P\"
  1059. XM(BH`#$ZZ##0I0`30("H`%"(J``Q.N@PD(BH`*)*J`"12@4ZZ#!;0J@`84X#BC
  1060. XMB"E`!-0@+`3,Y8`B*@`P+'@`!$ZN_SHI0`389B!*K`3T9Q9P$B(L`')![`%"+
  1061. XM)`@F`"QL!0A.KO_0<`!@`G`!3-],#$Y=3G4O#DJL!-AG$B`L!,SE@")L!-@L5
  1062. XM>``$3J[_+DJL!,AG#")L!,0L>``$3J[^/DJL!,1G"B\L!,1.N@LB6$]*K`3`X
  1063. XM9PHO+`3`3KH+/EA/+%].=4Y5_^A(YS<R)F\`1"1O`$@@;0`(+A!\S=RL!,PO/
  1064. XM"B\(80#[GE!/2H!G``$6+'@`!$ZN_WP@:@`(L>L`"&<B2JP$]&<``*1P$R(L*
  1065. XM`')![`%J)`@F`"QL!0A.KO_08```BB\'80#]PEA/+'@`!$ZN_W8@;`38+B@`*
  1066. XM"'H`8%(@!I"%Y8`@;`38T<`O$$AM_^Q(;?_P80#ZVD_O``P@+?_P(BP$Y-*`3
  1067. XM4X$D+?_L)BP$Z-:"4X,O00`@(&P$W")H`#(B`B0O`"`L;`4$3J[^SE*%NH=MY
  1068. XMJB`L!,SE@"!L!-C1P"XH__A*AV8`_T9^`&!$(&P$W"!H`%8L>``$3J[^@&`<W
  1069. XM#*H```(``!17P$0`2(!(P"X`(DHL>``$3J[^AB!L!-P@:`!6+'@`!$ZN_HPD5
  1070. XM0"`*9LY*AV>X(&P$W"QL!0!.KO^X3-],[$Y=3G5.5?_X2.<Q,B9O`"@@/```@
  1071. XM`01R`"QX``1.KO\Z+T``''`D<@!.KO\Z)$`@2B](`!@B"W3^+&P%"$ZN_ZPN0
  1072. XM`$JO`!QG``$R(`IG``$L2H=G``$,(@<D"DZN_XY*@&<``.0B!R0O`!Q.KO^:4
  1073. XM2H!G``#4(&\`'"`H``1*@&L>2JP$]&<``0QP$"(L`')#[`&2)`DF`$ZN_]!@Q
  1074. XM``#V("H`!$J`:AY*K`3T9P``YG`9(BP`<D/L`;8D"28`3J[_T&```-`@*@`<T
  1075. XMY8`F0"`+9AY*K`3T9P``O'`2(BP`<D/L`>HD"28`3J[_T&```*8O*P`(80#[)
  1076. XMDEA/)$`@"F<F+PIA`/P,6$]*@&<0+PHO"R\O`"1A`/VH3^\`#&$`_5`D;P`8\
  1077. XM8&XD;P`82JP$]&=D<!TB+`!R0>P"$B0()@`L;`4(3J[_T&!,2JP$]&=&<!HBU
  1078. XM+`!R0>P"3B0()@!.KO_08#)*K`3T9RQP#2(L`')![`*&)`@F`$ZN_]!@&$JL(
  1079. XM!/1G$G`,(BP`<D'L`J(D""8`3J[_T$J'9PHB!RQL!0A.KO^F2J\`'&<2(F\`K
  1080. XM'"`\```!!"QX``1.KO\N(`IG#")*<"0L>``$3J[_+DS?3(Q.74YU2.<S$BXO^
  1081. XM`!PF;P`@2H=6P$0`2(!(P"E`!/1#[`*^<``L>``$3J[]V"E`!0!G``"H0^P"S
  1082. XMT'``3J[]V"E`!01G>$J'9CI^`7P(8"P@:P`DT<8B:``$2A%G&B(0+&P%"$ZNE
  1083. XM_X(@:P`DT<8O*``$80#]QEA/4H=0AKZK`!QMSF!T<`&^@&8>2JP$]&=H<!(B$
  1084. XM+`!R0>P"XB0()@`L;`4(3J[_T&!0+`!8BV`*+QMA`/V(6$]2AKR';?)@.DJL[
  1085. XM!/1G-'`6(BP`<D'L`PHD""8`+&P%"$ZN_]!@'$JL!/1G%G`7(BP`<D'L`SHD1
  1086. XM""8`+&P%"$ZN_]!*K`4`9PPB;`4`+'@`!$ZN_F)*K`4$9PPB;`4$+'@`!$ZN0
  1087. XM_F)*K`!R9PPB+`!R+&P%"$ZN_]Q,WTC,3G5.=4YU3E7_Q$CG)S`F;P!<)&\`O
  1088. XM8'X`?`!Z`'``&WP`(/_[<@`K0?_V=/\K0O_R0>W_T!M`__$;0/_\*T'_Y"M!R
  1089. XM_^@K2/_,2A-G0G``$!-R&%U!:SBP>Q`(9O9.^Q`$`"-@```@`"!@```6`"M@)
  1090. XM```,`"U@```"?@%@#GP!8`IZ`6`&&WP``?_\4HM@NA`3<C"P`68&4HL;0?_[O
  1091. XM<"JP$V80(%)#Z``$)(DK4/_V4HM@#DAM__8O"TZZ!7!03]?`$!-R+K`!9B92%
  1092. XMBW`JL!-F$"!20^@`!"2)*U#_\E*+8`Y(;?_R+PM.N@5"4$_7P!`3<FRP`68*J
  1093. XM&WP``?_Q4HM@"')HL`%F`E*+$!MR`!(`&T#_\'`P74!K``)4LGL`"&;T3OL`L
  1094. XM!`!C8``"*@!S8``!Z`!88``!?@!X8``!>`!P8``!7@!O8``!#`!U8```X@!D=
  1095. XM8````DHM__%G#"!20^@`!"2)(!!@"B!20^@`!"2)(!`K0/_L;`IR`42M_^PKH
  1096. XM0?_H2JW_Z&<$<"U@"DH&9P1P*V`"<"`;0/_0<``0!B(M_^B"@'``$`6"@&<(>
  1097. XM4JW_S%*M_^0O+?_L+RW_S$ZZ`])03RM`_\@@+?_R2H!J!G(!*T'_\B`M_\@B&
  1098. XM+?_RDH!([0`"_\1O+B!M_\PB2-/!8`(2V%.`9/IP`!`M__LB+?_$(&W_S&`"-
  1099. XM$,!3@63Z("W_\BM`_\C1K?_D0>W_T"M(_\Q*!V<``5`;?``@__M@``%&2BW_E
  1100. XM\6<,(%)#Z``$)(D@$&`*(%)#Z``$)(D@$"M`_^Q@`/]B2BW_\6<,(%)#Z``$<
  1101. XM)(D@$&`*(%)#Z``$)(D@$"M`_^Q*+?_\9Q(@;?_,$/P`,'(!*T'_Y"M(_\PO)
  1102. XM`"\M_\Q.N@,L4$\K0/_(8`#_*!M\`##_^R`M__)*@&H&<`@K0/_R2BW_\6<,=
  1103. XM(%)#Z``$)(D@$&`*(%)#Z``$)(D@$"M`_^Q*+?_\9Q8@;?_,$/P`,!#\`'ARU
  1104. XM`BM!_^0K2/_,+P`O+?_,3KH#"%!/*T#_R'!8L"W_\&8`_KY(;?_03KH"&%A/,
  1105. XM8`#^L"!20^@`!"2)(E`K2?_,9@A!^@#<*TC_S"!M_\Q*&&;\4XB1[?_,*TC_"
  1106. XMY"`M__)*@&LJL<!O)BM`_^1@('`!*T#_Y"!20^@`!"2)(!`;0/_00BW_T6`&A
  1107. XM<`!@``",("W_Y"(M__:R@&P(=``K0O_V8`21K?_V2@=G-E.M_^1M&'``(&W_U
  1108. XMS!`8+P`K2/_,(&T`$$Z06$]@XE.M__9M2'``$"W_^R\`(&T`$$Z06$]@Z%.MO
  1109. XM__9M$G``$"W_^R\`(&T`$$Z06$]@Z%.M_^1M&'``(&W_S!`8+P`K2/_,(&T`&
  1110. XM$$Z06$]@XB`+3-\,Y$Y=3G4``$Y5__9(YP$P)F\`'B1O`"(K;0`0__8>&DH'1
  1111. XM9S1P);X`9B*P$F8$4HI@&B\+2&W_]B\*80#[S$_O``PK0/_Z9P0D0<``0L
  1112. XM!R\`3I-83V#&3-\,@$Y=3G5.5?]T2.<!,"9O`*!^`'`@OH!L``""$!-R(+`!4
  1113. XM9PQR";`!9P9R"K`!9@12BV#H2A-G9"`'Y8!2AT'M_W31P"1(<"*P$V8F4HLD5
  1114. XMBTH39PIP(K`39P12BV#R2A-F#$AX``%.N@!:6$]@ID(;8*(DBTH39Q@0$W(@&
  1115. XML`%G$'()L`%G"G(*L`%G!%*+8.1*$V8"8`9"&V``_WI*AV<&0>W_=&`$(&P`N
  1116. XM7B\(+P=.NOG,0I=.N@`,3.T,@/]H3EU.=4[Y````&````````$CG(#`F;P`0B
  1117. XM)$M*$F<D<``0$D'L`VT(,``!"`!G"G(`$@!T()*"8`1R`!(`%(%2BF#8(`M,K
  1118. XMWPP$3G4``````````'!A(F\`""!O``0@+P`,(@A@!!#99PA3@&3X8`9"&%.`R
  1119. XM9/H@`4YU("\`""!O``1.5?_T(D]R"DZZ`>@&00`P$L%*@&;P(`D0X;_)9OI".
  1120. XM$)"/3EU.=0``("\`""!O``1.5?_T(D\B``)!``<&00`P$L'FB&;P(`D0X;_)J
  1121. XM9OI"$)"/3EU.=0``,#$R,S0U-C<X.6%B8V1E9B`O``@@;P`$0^\`!#(``D$`V
  1122. XM#Q+[$-SHB&;R(`DB#UB!$.&RB6;Z0A"0@4YU(&\`!")(<@!P`"\"#!``*V<&Y
  1123. XM#!``+68"4D@0&`0``#!M$@P```EN#"0!Y8'2@M*!TH!@Y@P1`"UF`D2!)!\@9
  1124. XM"%.`(&\`"""!D(E.=2\'+B\`"%*L!/P@!R!L!/@0P"E(!/@N'TYU3E4``$CG6
  1125. XM`#`F;P`0)&\`%$*L!/PI2P3X2&T`$"\*2'K_QDZZ_5(@;`3X0A`@+`3\3.T,A
  1126. XM`/_X3EU.=4CG`!(F;P`,%WP`_P`(,'S__R=(`!0G2``8(DMP,"QX``1.KO\NS
  1127. XM3-](`$YU2.<`$B9O``Q*JP`*9PHB2RQX``1.KOZ8%WP`_P`(</\G0``4<``0S
  1128. XM*P`/+'@`!$ZN_K`B2W`B3J[_+DS?2`!.=4CG,``D`"8!2$)(0\3!QL#`P=1#,
  1129. XM2$)"0M""3-\`#$YU2H!J```>1(!*@6H```Q$@6$``"!$@4YU80``&$2`1(%./
  1130. XM=4J!:@``#$2!80``!D2`3G4O`DA!-`%F```B2$!(04A"-`!G```&A,$P`DA`;
  1131. XM-`"$P3`"2$(R`B0?3G4O`W80#$$`@&0```;AF5%##$$(`&0```;IF5E##$$@V
  1132. XM`&0```;EF55#2D%K```&XYE30S0`YJA(0D)"YJI(0X#!-@`P`C0#2$'$P9""Y
  1133. XM9```"%-#T(%D_G(`,@-(0^>X2$#!028?)!].=4CG`#(F;P`0(`MF!'``8"9P<
  1134. XM,"(\``$``2QX``1.KO\Z)$`@"F<.%7P`!0`(0BH`"25+``X@"DS?3`!.=4CG4
  1135. XM`S(F;P`8+B\`''#_+'@`!$ZN_K8L``P&`/]F!'``8&9P(B(\``$``4ZN_SHD*
  1136. XM0"`*9@IP`!`&3J[^L&!()4L`"B`'%4``"15\``0`"$(J``X51@`/D\E.KO[:B
  1137. XM)4``$"`+9P@B2DZN_IY@&D'J`!@E2``40>H`%"5(`!Q"J@`8%7P``@`@(`I,&
  1138. XMWTS`3G4``$CG`#(F;`4,(`MG%"13(DL@*P`(+'@`!$ZN_RXF2F#HD<@I2`40W
  1139. XM*4@%#$S?3`!.=0```^P````!`````@``#>X````````#\@```^H```$<````H
  1140. XM`````````````````0````$```#F3OD`````````````````````````````O
  1141. XM`````````````````````````````````````````````````````````````
  1142. XM``````````````````````````````````````!D;W,N;&EB<F%R>0`J````3
  1143. XM!]!B;&]C:W,``````(P``````````0``````````__\```(```,`#@``````S
  1144. XM`````````````````````````````````49I;&4Z("5S+"`E;&0@8FQO8VMS2
  1145. XM``!.;R!P;W)T(0H`3F\@<&]R="$*`$YO($E/(')E<75E<W0A"@!.;R!)3R!RJ
  1146. XM97%U97-T(0H`1&5V:6-E(&YO="!O<&5N960*``!$979I8V4@;F]T(&]P96YE@
  1147. XM9`H``$YO('-E8W1O<B!B=69F97(A"@``3F\@<V5C=&]R(&)U9F9E<B$*``!$6
  1148. XM:7-K(&YO="!I;B!D<FEV92$*`$1I<VL@;F]T(&EN(&1R:79E(0H`3VYL>2!F4
  1149. XM;W(@9FEL97,A"@``3VYL>2!F;W(@9FEL97,A"@``3VYL>2!O;B!/1E,@;W(@N
  1150. XM1D93(&1I<VMS"@!/;FQY(&]N($]&4R!O<B!&1E,@9&ES:W,*`$1I<VL@;F]T2
  1151. XM(&EN(&1R:79E"@``1&ES:R!N;W0@:6X@9')I=F4*``!#;W5L9&XG="!F:6YDS
  1152. XM(&1I<VLG<R!D979I8V4A"@!#;W5L9&XG="!F:6YD(&1I<VLG<R!D979I8V4AW
  1153. XM"@!#;W5L9&XG="!G970@:6YF;R!O;B!F:6QE"@``0V]U;&1N)W0@9V5T(&EN4
  1154. XM9F\@;VX@9FEL90H``$YO('-U8V@@9FEL90H`3F\@<W5C:"!F:6QE"@!.;R!M:
  1155. XM96UO<GD@(0H``$YO(&UE;6]R>2`A"@``:6YT=6ET:6]N+FQI8G)A<GD`9W)AX
  1156. XM<&AI8W,N;&EB<F%R>0``8FQO8VMS(#QF:6QE;F%M93X*``!B;&]C:W,@/&9I&
  1157. XM;&5N86UE/@H``$YO(&=R87!H:6-S(&QI8G)A<GD@(0H``$YO(&=R87!H:6-SV
  1158. XM(&QI8G)A<GD@(0H``$YO(&EN='5I=&EO;B!L:6)R87)Y("$*`$YO(&EN='5I&
  1159. XM=&EO;B!L:6)R87)Y("$*`````"`@("`@("`@("@H*"@H("`@("`@("`@("`@"
  1160. XM("`@("`@2!`0$!`0$!`0$!`0$!`0$(2$A(2$A(2$A(00$!`0$!`0@8&!@8&!6
  1161. XM`0$!`0$!`0$!`0$!`0$!`0$!`0$0$!`0$!""@H*"@H("`@("`@("`@("`@(":
  1162. XM`@("`@("`A`0$!`@("`@("`@("`@*"@H*"@@("`@("`@("`@("`@("`@("!(>
  1163. XM$!`0$!`0$!`0$!`0$!`0A(2$A(2$A(2$A!`0$!`0$!"!@8&!@8$!`0$!`0$!5
  1164. XM`0$!`0$!`0$!`0$!`1`0$!`0$(*"@H*"@@("`@("`@("`@("`@("`@("`@("A
  1165. X@$!`0$"````````/L`````0````(```"4`````````_("=
  1166. X``
  1167. Xend
  1168. Xsize 6692
  1169. SHAR_EOF
  1170. echo "End of archive 1 (of 1)"
  1171. # if you want to concatenate archives, remove anything after this line
  1172. exit
  1173.